package com.joeljhou.project.core.data;

import com.joeljhou.project.form.Component;
import com.joeljhou.project.pojo.Quality;
import com.joeljhou.project.pojo.ReportData;
import lombok.Data;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

/**
 * 监听数据接收
 */
@Data
public class DataListener implements Observer {

    //头数据效验
    private static final String HEAD_VALIDA = "01 03 ";

    //格式化日期
    private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //数据格式化
    private static final DecimalFormat DATA_FORMAT = new DecimalFormat("#.###");

    //接收的数据
    public static final List<ReportData> listData = new ArrayList<>();

    public static final Map<String, String> mapStatistics = new HashMap<>();

    //最大值
    private static Integer max;
    //最小值
    private static Integer min;
    //平均值
    private static Double ave;

    //良品数量
    private static long good;
    //非良品数量
    private static long bag;
    //OK/NG
    private static Quality quality;

    @Override
    public void update(Observable o, Object arg) {
        Component component = Component.getInstance();
        JTextPane dataArea = component.getDataArea();

        String receivedData = (String) arg;
        //boolean validate = validateHeader(receivedData);
        //if (!validate) {
        //    //非法数据处理 直接将原始16进制打印到数据展示面板
        //    dataArea.append(receivedData + "\r\n");
        //    dataArea.setCaretPosition(dataArea.getDocument().getLength());
        //}
        //解析数据
        Integer num = parseHexData(receivedData);
        String dateFormat = DATETIME_FORMAT.format(new Date());
        listData.add(new ReportData(dateFormat, num));

        //实时赋值变量
        JTextField pullTextField = component.getPullTextField();
        String pullText = pullTextField.getText();
        double pullValue = Double.parseDouble(pullText);  //拉力值

        max = listData.stream().map(ReportData::getValue).max(Integer::compareTo).get();
        min = listData.stream().map(ReportData::getValue).min(Integer::compareTo).get();
        ave = listData.stream().map(ReportData::getValue).mapToInt(i -> i).average().getAsDouble();
        good = listData.stream().map(ReportData::getValue).filter(i -> i / 1000.0 >= pullValue).count();
        bag = listData.stream().map(ReportData::getValue).filter(i -> i / 1000.0 < pullValue).count();
        quality = num / 1000 >= pullValue ? Quality.GOOD : Quality.BAG;

        //输出到数据展示
        String dataTxt = dateFormat + "\t" + DATA_FORMAT.format(num / 1000.0) + "\r\n";
        if (quality.getState()) {
            component.appendText(dataTxt);
        } else {
            component.appendText(dataTxt, Color.RED);
        }
        dataArea.setCaretPosition(dataArea.getDocument().getLength());

        //输出到表格
        JTable table = component.getStatisticsTable();
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        String maxStr = DATA_FORMAT.format(max / 1000.0);
        String minStr = DATA_FORMAT.format(min / 1000.0);
        String avgStr = DATA_FORMAT.format(ave / 1000.0);
        model.setValueAt(maxStr, 0, 1);  //修改第1行第2列的数据
        model.setValueAt(minStr, 1, 1);
        model.setValueAt(avgStr, 2, 1);
        model.setValueAt(listData.size(), 3, 1);
        model.setValueAt(good, 4, 1);
        model.setValueAt(bag, 5, 1);

        //OK/NG控制
        JToggleButton toggleBtn = component.getToggleBtn();
        toggleBtn.setSelected(quality.getState());

        mapStatistics.put("max", maxStr);
        mapStatistics.put("min", minStr);
        mapStatistics.put("avg", avgStr);
        mapStatistics.put("total", String.valueOf(listData.size()));
        mapStatistics.put("good", String.valueOf(good));
        mapStatistics.put("bag", String.valueOf(bag));
    }


    //行数据头效验证
    private boolean validateHeader(String lineData) {
        return lineData.startsWith(HEAD_VALIDA);
    }

    //解析16进制数据
    private static Integer parseHexData(String lineData) {
        final String serialData = lineData.substring(6).trim();
        if (serialData.length() == 0) {
            return null;
        }
        //高低位互换，数据解析成10进制
        String[] serialArray = serialData.split(" ");
        String hexData = serialArray[1] + serialArray[0];
        int decimalData = Integer.parseInt(hexData, 16);
        return decimalData;
    }
}
